package com.miplus.ccrm.core.service.aicall;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.*;
import com.miplus.ccrm.core.controller.vo.aicall.*;
import com.miplus.ccrm.core.controller.vo.ficase.ImpDelReqVo;
import com.miplus.ccrm.core.controller.vo.ficase.ImpResultVo;
import com.miplus.ccrm.core.controller.vo.strategy.ActDataColVo;
import com.miplus.ccrm.core.controller.vo.strategy.PreViewTrigReqVo;
import com.miplus.ccrm.core.mapper.CpCalllistMapper;
import com.miplus.ccrm.core.mapper.CpCalllistTriggerMapper;
import com.miplus.ccrm.core.mapper.ObJobStatusMapper;
import com.miplus.ccrm.core.pojo.*;
import com.miplus.ccrm.core.mapper.ObCallCaseMapper;
import com.miplus.ccrm.core.service.ExportService;
import com.miplus.ccrm.core.service.JRbtLinker;
import com.miplus.ccrm.core.service.collect.FiCreditcasesService;
import com.miplus.ccrm.core.service.collect.FiImportHistService;
import com.miplus.ccrm.core.service.strategy.CpCalllistTriggerQuerylinkService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
* @author pc
* @description 针对表【OB_CALL_CASE(AI外呼表)】的数据库操作Service实现
* @createDate 2024-10-30 17:53:19
*/
@Service
@Slf4j
public class ObCallCaseServiceImpl extends MPJBaseServiceImpl<ObCallCaseMapper, ObCallCase>
    implements ObCallCaseService{
    @Resource
    private FiImportHistService fiImportHistService;
    @Resource
    private CpCalllistTriggerMapper triggerMapper;
    @Resource
    private FiCreditcasesService caseService;
    @Resource
    private ExportService exportService;
    @Resource
    private CpCalllistMapper cpCalllistMapper;
    @Resource
    private JRbtLinker rbtLinker;
    @Resource
    private ObJobStatusMapper obJobStatusMapper;
    @Resource
    private CpCalllistTriggerQuerylinkService triggerQuerylinkService;

    @Override
    public IPage<ObCallListResVo> dialList(ObCallListReqVo paras)
    {
        return selectJoinListPage(new Page<>(paras.getPageNum(), paras.getPageSize()),
                ObCallListResVo.class,
                new MPJLambdaWrapper<ObCallCase>()
                        .selectAs(ObCallCase::getCaseid,ObCallListResVo::getDataid)
                        .selectAs(ObCallCase::getPdJobid,ObCallListResVo::getClid)
                        .selectAs(ObCallCase::getFicaseid,ObCallListResVo::getFicaseid)
                        .selectAs(ObCallCase::getUf1,ObCallListResVo::getCustname)
                        .selectAs(ObCallCase::getUf2,ObCallListResVo::getOdudprin)
                        .selectAs(ObCallCase::getUf3,ObCallListResVo::getMthsday)
                        .selectAs(ObCallCase::getUf4,ObCallListResVo::getRepayday)
                        .selectAs(ObCallCase::getDialdt,ObCallListResVo::getDialdt)
                        .selectAs(ObCallCase::getPdDialcnt, ObCallListResVo::getDialcnt)
                        .selectAs(ObCallCase::getPdCcc, ObCallListResVo::getCcc)
                        .selectAs(ObCallCase::getPdStatus, ObCallListResVo::getPdstatus)
                        .selectAs("dbo.fun_getnames('CAMPAIGN.CB.STATUS',t.pd_status)", ObCallListResVo::getPdstatusdsc)
                        .selectAs("(select cp.name from cp_calllist cp where cp.clid=t.pd_jobid)", ObCallListResVo::getClidname)
                        .selectAs("(select g.helpstr from cp_strategy g where g.ccc=t.pd_ccc and g.clid=t.pd_jobid)", ObCallListResVo::getCccdsc)
                        .select(ObCallCase::getCrdt,ObCallCase::getPhone,ObCallCase::getBatchid)
                        .eq(JPubUtils.IsNotEmpty(paras.getBatchid()), ObCallCase::getBatchid, paras.getBatchid())
                        .eq(JPubUtils.IsNotEmpty(paras.getClid()), ObCallCase::getPdJobid, paras.getClid())
                        .eq(JPubUtils.IsNotEmpty(paras.getPdstatus()), ObCallCase::getPdCurstatus, paras.getPdstatus())
                        .eq(JPubUtils.IsNotEmpty(paras.getFicaseid()), ObCallCase::getAccountid, paras.getFicaseid())
                        .eq(JPubUtils.IsNotEmpty(paras.getPhone()), ObCallCase::getPhone, paras.getPhone())
                        .between(JPubUtils.IsNotEmpty(paras.getStartdt()), ObCallCase::getCrdt, JPubUtils.StringToDate(paras.getStartdt()), JPubUtils.StringToDate(paras.getEnddt()))
                        .eq(JPubUtils.IsNotEmpty(paras.getCcc()), ObCallCase::getPdCcc, paras.getCcc())
                        .between(JPubUtils.IsNotEmpty(paras.getCallstartdt()), ObCallCase::getDialdt, JPubUtils.StringToDate(paras.getCallstartdt()), JPubUtils.StringToDate(paras.getCallenddt()))
                        .orderByDesc(ObCallCase::getDialdt)
        );
    }

    @Override
    public CmdResVo updateDataStatus(UpDataStatusReqVo statusReqVo)
    {
        int ret=0;
        if(JPubUtils.IsEqual(statusReqVo.getStatus(),"1")) {
            ret=baseMapper.update(null,
                    new UpdateWrapper<ObCallCase>()
                            .lambda()
                            .eq(ObCallCase::getBatchid, statusReqVo.getBatchid())
                            .eq(ObCallCase::getPdCurstatus,"N")
                            .set(ObCallCase::getPdCurstatus,"O")
                            .set(ObCallCase::getPdStatus,"O")
            );
        }else{
            ret=baseMapper.update(null,
                    new UpdateWrapper<ObCallCase>()
                            .lambda()
                            .eq(ObCallCase::getBatchid, statusReqVo.getBatchid())
                            .eq(ObCallCase::getPdCurstatus,"O")
                            .set(ObCallCase::getPdCurstatus,"N")
                            .set(ObCallCase::getPdStatus,"N")
            );
        }

        FiImportHist hist=new FiImportHist();
        hist.setStatus(JPubUtils.StringToInt(statusReqVo.getStatus()));
        hist.setBatchid(statusReqVo.getBatchid());
        fiImportHistService.updateById(hist);

        return new CmdResVo(ret,statusReqVo.getBatchid());
    }

    @Override
    public CmdResVo updateCallStatus(UpCallStatusVo callStatusVo)
    {
        int ret=baseMapper.update(null,new UpdateWrapper<ObCallCase>()
                .lambda()
                .eq(ObCallCase::getCaseid,callStatusVo.getCaseid())
                .set(ObCallCase::getPdStatus,callStatusVo.getNewstatus())
                .set(ObCallCase::getPdCurstatus,callStatusVo.getNewstatus())
                .set(ObCallCase::getPdResult,0)
                .set(ObCallCase::getPdComplete,"0")
                .set(ObCallCase::getPdDt2d,null)
        );
        return new CmdResVo(ret,callStatusVo.getCaseid());
    }

    private MPJLambdaWrapper getQueryWrapper(Integer triggerid)
    {
        String noinctags="";
        CpCalllistTrigger trigger=triggerMapper.selectById(triggerid);
        String tags= JPubUtils.getInString(trigger.getCusttags());
        if(JPubUtils.IsNotEmpty(tags)){
            noinctags = JPubUtils.BoolToString(trigger.getNoinctag());
        }

        MPJLambdaWrapper quyWrapper=new MPJLambdaWrapper<FiCreditcases>()
                .innerJoin(ConCustomer.class, "cu", ConCustomer::getCustomernumber, FiCreditcases::getCustomernumber)
                .ge(JPubUtils.IsNotEmpty(trigger.getMthsodue()), FiCreditcases::getMthsOdue, trigger.getMthsodue())
                .le(JPubUtils.IsNotEmpty(trigger.getMthsodue2()), FiCreditcases::getMthsOdue, trigger.getMthsodue2())
                .ge(JPubUtils.IsNotEmpty(trigger.getOverday1()), FiCreditcases::getMthsDay, trigger.getOverday1())
                .le(JPubUtils.IsNotEmpty(trigger.getOverday2()), FiCreditcases::getMthsDay, trigger.getOverday2())
                .isNotNull(ConCustomer::getCustphone)
                .apply(JPubUtils.IsEqual(noinctags, 0),String.format("cu.customernumber in (select tag.custid from con_customertag tag where tag.custid=t.customernumber and tag.id in ('%s'))", tags))
                .apply(JPubUtils.IsEqual(noinctags, 1), String.format("cu.customernumber not in (select tag.custid from con_customertag tag where tag.custid=t.customernumber and tag.id in ('%s'))", tags));

        quyWrapper=triggerQuerylinkService.buildQueryWrapper(quyWrapper,triggerid);

        return quyWrapper;
    }

    @Override
    public IPage<ImpObCaseResVo> preViewQmData(String triggerid, Integer pagenum, Integer pagesize)
    {
        Integer trint=Integer.parseInt(triggerid);
        MPJLambdaWrapper<FiCreditcases> quyWrapper=getQueryWrapper(trint);
        return caseService.selectJoinListPage(new Page<>(pagenum, pagesize),
                ImpObCaseResVo.class,
                quyWrapper.selectAs(FiCreditcases::getCreditcaseid, ImpObCaseResVo::getFicaseid)
                        .selectAs(ConCustomer::getCustphone, ImpObCaseResVo::getPhone)
                        .selectAs(FiCreditcases::getCustomernumber,ImpObCaseResVo::getCustomerid)
                        .selectAs(FiCreditcases::getCreditAcct, ImpObCaseResVo::getAccountid)
                        .select(FiCreditcases::getOdudPrin,FiCreditcases::getMthsDay,FiCreditcases::getRepayday)
                        .select(ConCustomer::getCustomernumber, ConCustomer::getCustname)
        );
    }

    @Override
    public IPage<ImpObCaseResVo> quyImpObHist(PreViewTrigReqVo paras)
    {
        CpCalllist calllist=cpCalllistMapper.selectById(paras.getClid());
        String triggerid=calllist.getTriggerid();
        if(JPubUtils.IsEmpty(triggerid)){
            throw new ServiceException(EnumRCode.NoFindConfig.value, EnumRCode.NoFindConfig.name);
        }
        return preViewQmData(triggerid,1,JPubUtils.exportMaxCount);
    }

    private List<ImpObCaseResVo> buildImpData(String triggerid)
    {
        IPage<ImpObCaseResVo> pages=preViewQmData(triggerid,1,JPubUtils.exportMaxCount);
        return pages.getRecords();
    }

    private List<ImpObCaseResVo> buildImpData(List<ImpObItemVo> list)
    {
        List<ImpObCaseResVo> pagelist=new ArrayList<>();
        for(ImpObItemVo resVo : list){
            ImpObCaseResVo p=new ImpObCaseResVo();
            p.setPhone(resVo.getPhone());
            p.setCustname(resVo.getCustname());
            p.setCustomerid(resVo.getCustomerid());
            p.setAccountid(resVo.getAccountid());
            p.setMthsday(resVo.getMthsday());
            p.setOdudprin(resVo.getOdudprin());
            p.setRepayday(resVo.getRepayday());
            pagelist.add(p);
        }

        return pagelist;
    }

    @Override
    public ImpResultVo impObCase(String $usrid, ImpObCallReqVo paras)
    {
        ImpResultVo resultVo=null;
        String imptype=paras.getImptype();
        if(JPubUtils.IsEqual(imptype,"file")) {
            List<ImpObCaseResVo> list=buildImpData(paras.getAddVoList());
            resultVo=impObCase($usrid,paras.getClid(),"",paras.getBatchdsc(),imptype,list);
        }else{
            CpCalllist calllist=cpCalllistMapper.selectById(paras.getClid());
            String triggerid=calllist.getTriggerid();
            if(JPubUtils.IsEmpty(triggerid)){
                throw new ServiceException(EnumRCode.NoFindConfig.value, EnumRCode.NoFindConfig.name);
            }
            resultVo=impObCase($usrid,calllist.getClid(),triggerid,paras.getBatchdsc(),imptype);
        }
        return resultVo;
    }

    @Override
    public ImpResultVo impObCase(String $usrid,String clid,String triggerid,String batchdsc,String imptype)
    {
        List<ImpObCaseResVo> list=buildImpData(triggerid);
        return impObCase($usrid,clid,triggerid,batchdsc,imptype,list);
    }


    public ImpResultVo impObCase(String $usrid,String clid,String triggerid,String batchdsc,
                                 String imptype,List<ImpObCaseResVo> list)
    {
        int okcnt=0;
        SimpleDateFormat df = new SimpleDateFormat("yyMMddHHmmssSSS");
        String batchid='D'+df.format(new Date());
        //先写一个后面在update，目的是为了写入数据异常，可以delete掉
        fiImportHistService.AddImportHist(batchid,
                batchdsc,
                $usrid,
                0,
                "dialtemplate",
                triggerid,
                list.size(),
                okcnt,
                clid,
                imptype
        );
        log.info("impObCase:Records={}",list.size());
        List<ObCallCase> dataList=new ArrayList<>();
        for(ImpObCaseResVo p : list){
            ObCallCase obcase=new ObCallCase();
            obcase.setPriority("10");
            obcase.setBatchid(batchid);
            obcase.setPdStatus("N");
            obcase.setPdCurstatus("N");
            obcase.setPdJobid(clid);
            obcase.setCrdt(new Date());
            obcase.setPhone(p.getPhone());
            obcase.setAccountid(p.getAccountid());
            obcase.setPdCustomerid(p.getCustomerid());
            obcase.setUf1(p.getCustname());
            if(JPubUtils.IsNotEmpty(p.getFicaseid())){
                obcase.setFicaseid(p.getFicaseid());
            }
            if(p.getOdudprin()==null){
                obcase.setUf2("0");
            }else {
                obcase.setUf2(p.getOdudprin().toString());
            }
            if(p.getMthsday()==null){
                obcase.setUf3("0");
            }else {
                obcase.setUf3(p.getMthsday().toString());
            }
            obcase.setUf4(p.getRepayday());
            dataList.add(obcase);
            okcnt++;
        }
        saveBatch(dataList);

        fiImportHistService.UpImportHist(batchid,okcnt);
        list.clear();

        ImpResultVo resultVo=new ImpResultVo();
        resultVo.setBatchid(batchid);
        resultVo.setOkcnt(okcnt);
        resultVo.setFailcnt(0);

        return resultVo;
    }

    @Override
    public IPage<TotalRepResVo> repJobTotal(TotalRepReqVo paras)
    {
        return baseMapper.quyJobTotalReport(new Page<>(paras.getPageNum(), paras.getPageSize()),
                paras.getClid(),paras.getReporttype(),
                paras.getStartdate(),paras.getEnddate()
        );
    }

    @Override
    public IPage<BatchRepResVo> repJobBatch(BatchRepReqVo paras)
    {
        return baseMapper.quyJobBatchReport(new Page<>(paras.getPageNum(), paras.getPageSize()),
                paras.getClid(),paras.getBatchid()
        );
    }

    @Override
    public CmdResVo expJobTotal(JSysUser user, TotalRepReqVo paras, HttpServletResponse response)
    {
        String $usrid = user.getUsrid();
        int pagesize = paras.getPageSize();
        if (pagesize > JPubUtils.exportMaxCount) {
            paras.setPageSize(JPubUtils.exportMaxCount);
        }
        log.info("expJobTotal:pagesize={}",pagesize);

        IPage<TotalRepResVo> pages=repJobTotal(paras);
        ArrayList arr=new ArrayList();

        String exptempid=JPubUtils.getExpTempID(paras.getExpfilename(),"外呼任务统计表");
        String filename=JPubUtils.getExpFileName(
                paras.getExpfilename(),exptempid
        );
        pages.convert(u->{
            HashMap map=JPubUtils.toExportMap(u);
            if(map!=null) arr.add(map);
            return u;
        });
        CmdResVo resVo=exportService.ToExcel(
                response,
                arr,
                paras.getExpidlist(),
                paras.getExpnamelist(),
                filename,
                $usrid
        );

        int okcount=resVo.getCount();
        if(okcount>0){
            fiImportHistService.AddExportHist(
                    resVo.getKeyId(),
                    $usrid,
                    exptempid,
                    filename,
                    okcount
            );
        }
        arr.clear();

        return resVo;
    }

    @Override
    public CmdResVo expJobBatch(JSysUser user, BatchRepReqVo paras, HttpServletResponse response)
    {
        String $usrid = user.getUsrid();
        int pagesize = paras.getPageSize();
        if (pagesize > JPubUtils.exportMaxCount) {
            paras.setPageSize(JPubUtils.exportMaxCount);
        }
        log.info("expJobBatch:pagesize={}",pagesize);

        IPage<BatchRepResVo> pages=repJobBatch(paras);
        ArrayList arr=new ArrayList();

        String exptempid=JPubUtils.getExpTempID(paras.getExpfilename(),"外呼批次统计表");
        String filename=JPubUtils.getExpFileName(
                paras.getExpfilename(),exptempid
        );
        pages.convert(u->{
            HashMap map=JPubUtils.toExportMap(u);
            if(map!=null) arr.add(map);
            return u;
        });
        CmdResVo resVo=exportService.ToExcel(
                response,
                arr,
                paras.getExpidlist(),
                paras.getExpnamelist(),
                filename,
                $usrid
        );

        int okcount=resVo.getCount();
        if(okcount>0){
            fiImportHistService.AddExportHist(
                    resVo.getKeyId(),
                    $usrid,
                    exptempid,
                    filename,
                    okcount
            );
        }
        arr.clear();

        return resVo;
    }

    @Override
    public CmdResVo expDialList(JSysUser user, ObCallListReqVo paras, HttpServletResponse response)
    {
        String $usrid = user.getUsrid();
        int pagesize = paras.getPageSize();
        if (pagesize > JPubUtils.exportMaxCount) {
            paras.setPageSize(JPubUtils.exportMaxCount);
        }
        log.info("expDialList:pagesize={}",pagesize);

        IPage<ObCallListResVo> pages=dialList(paras);
        ArrayList arr=new ArrayList();

        String exptempid=JPubUtils.getExpTempID(paras.getExpfilename(),"外呼数据");
        String filename=JPubUtils.getExpFileName(
                paras.getExpfilename(),exptempid
        );
        pages.convert(u->{
            HashMap map=JPubUtils.toExportMap(u);
            if(map!=null) arr.add(map);
            return u;
        });
        CmdResVo resVo=exportService.ToExcel(
                response,
                arr,
                paras.getExpidlist(),
                paras.getExpnamelist(),
                filename,
                $usrid
        );

        int okcount=resVo.getCount();
        if(okcount>0){
            fiImportHistService.AddExportHist(
                    resVo.getKeyId(),
                    $usrid,
                    exptempid,
                    filename,
                    okcount
            );
        }
        arr.clear();

        return resVo;
    }

    @Override
    public CmdResVo dialAdmin(DialAdminCmdVo cmdVo)
    {//{jobid:aidial,cmd:start}
        String cmd= JSONObject.toJSONString(cmdVo.getData());
        int iret = rbtLinker.SendDialerCmd(cmd);
        return new CmdResVo(iret,cmdVo.getJobid());
    }

    @Override
    public CmdResVo getDialJobStatus(String jobid)
    {
        ObJobStatus jobStatus=obJobStatusMapper.selectById(jobid);
        Integer status=0;
        if(jobStatus==null){
            log.warn("getDialJobStatus.Nofind:",jobid);
        }
        else{
            status=jobStatus.getStatus();
        }
        return new CmdResVo(status,jobid);
    }
}




